import cv2
from PIL import Image
from pylab import*
import os
import psycopg2
import numpy as np
import matplotlib.pyplot as plt

class LBP:
    def __init__(self):
        self.revolve_map={0:0,1:1,3:2,5:3,7:4,9:5,11:6,13:7,15:8,17:9,19:10,21:11,23:12,
                          25:13,27:14,29:15,31:16,37:17,39:18,43:19,45:20,47:21,51:22,53:23,55:24,
                          59:25,61:26,63:27,85:28,87:29,91:30,95:31,111:32,119:33,127:34,255:35}
        self.uniform_map={0:0,1:1,2:2,3:3,4:4,6:5,7:6,8:7,12:8,
                          14:9,15:10,16:11,24:12,28:13,30:14,31:15,32:16,
                          48:17,56:18,60:19,62:20,63:21,64:22,96:23,112:24,
                          120:25,124:26,126:27,127:28,128:29,129:30,131:31,135:32,
                          143:33,159:34,191:35,192:36,193:37,195:38,199:39,207:40,
                          223:41,224:42,225:43,227:44,231:45,239:46,240:47,241:48,
                          243:49,247:50,248:51,249:52,251:53,252:54,253:55,254:56,
                          255:57}


    def describe(self,image):
        image_array=np.array(Image.open(image).convert('L'))
        return image_array

    def calute_basic_lbp(self,image_array,i,j):
        sum=[]
        if image_array[i-1,j-1]>image_array[i,j]:
            sum.append(1)
        else:
            sum.append(0)
        if image_array[i-1,j]>image_array[i,j]:
            sum.append(1)
        else:
            sum.append(0)
        if image_array[i-1,j+1]>image_array[i,j]:
            sum.append(1)
        else:
            sum.append(0)
        if image_array[i,j-1]>image_array[i,j]:
            sum.append(1)
        else:
            sum.append(0)
        if image_array[i,j+1]>image_array[i,j]:
            sum.append(1)
        else:
            sum.append(0)
        if image_array[i+1,j-1]>image_array[i,j]:
            sum.append(1)
        else:
            sum.append(0)
        if image_array[i+1,j]>image_array[i,j]:
            sum.append(1)
        else:
            sum.append(0)
        if image_array[i+1,j+1]>image_array[i,j]:
            sum.append(1)
        else:
            sum.append(0)
        return sum

    #获取二进制序列进行不断环形旋转得到新的二进制序列的最小十进制值
    def get_min_for_revolve(self,arr):
        values=[]
        circle=arr
        circle.extend(arr)
        for i in range(0,8):
            j=0
            sum=0
            bit_num=0
            while j<8:
                sum+=circle[i+j]<<bit_num
                bit_num+=1
                j+=1
            values.append(sum)
        return min(values)

    #获取值r的二进制中1的位数
    def calc_sum(self,r):
        num=0
        while(r):
            r&=(r-1)
            num+=1
        return num

    #获取图像的LBP原始模式特征
    def lbp_basic(self,image_array):
        basic_array=np.zeros(image_array.shape, np.uint8)
        width=image_array.shape[0]
        height=image_array.shape[1]
        for i in range(1,width-1):
            for j in range(1,height-1):
                sum=self.calute_basic_lbp(image_array,i,j)
                bit_num=0
                result=0
                for s in sum:
                    result+=s<<bit_num
                    bit_num+=1
                basic_array[i,j]=result
        return basic_array


if __name__ == '__main__':
    conn = psycopg2.connect(
        host="YOUR_HOST",
        port="YOUR_PORT",
        user="YOUR_USER",
        password="YOUR_PASSWORD",
        database="YOUR_DATABASE"
    )

    drop_table_query = """
        DROP TABLE feature_vectors ;
        """
    cursor = conn.cursor()
    cursor.execute(drop_table_query)
    conn.commit()

    # 创建表
    create_table_query = """
    CREATE TABLE IF NOT EXISTS feature_vectors (
        id SERIAL PRIMARY KEY,
        filename VARCHAR(255),
        vector TEXT,
        distance REAL
    );
    """
    cursor = conn.cursor()
    cursor.execute(create_table_query)
    conn.commit()

    # 插入数据
    dataset_path = r"E:\IMDB\wiki1"
    lbp = LBP()

    for filename in os.listdir(dataset_path):
        if filename.endswith(".jpg"):
            image_path = os.path.join(dataset_path, filename)
            image_array = lbp.describe(image_path)

            # 获取图像原始LBP特征，并输出特征向量
            basic_array = lbp.lbp_basic(image_array)
            h, _ = np.histogram(basic_array, bins=256, range=(0, 256))
            feature_vector = h.tolist()  # 转换为列表格式

            # 插入数据
            insert_query = "INSERT INTO feature_vectors (filename, vector) VALUES (%s, %s);"
            cursor.execute(insert_query, (filename, feature_vector))
            conn.commit()

    # 关闭连接
    cursor.close()
    conn.close
